package com.uduemc.biso.node.web.api.controller;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

import javax.validation.Valid;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.CollectionUtils;
import org.springframework.validation.BindingResult;
import org.springframework.validation.FieldError;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import com.fasterxml.jackson.core.JsonParseException;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.JsonMappingException;
import com.github.pagehelper.PageInfo;
import com.uduemc.biso.core.utils.JsonResult;
import com.uduemc.biso.node.core.entities.SFaq;
import com.uduemc.biso.node.core.entities.SSystem;
import com.uduemc.biso.node.core.entities.custom.Faq;
import com.uduemc.biso.node.core.node.extities.FaqTableData;
import com.uduemc.biso.node.core.utils.FilterResponse;
import com.uduemc.biso.node.web.api.dto.RequestFaq;
import com.uduemc.biso.node.web.api.dto.RequestFaqTableDataList;
import com.uduemc.biso.node.web.api.service.FaqService;
import com.uduemc.biso.node.web.api.service.SystemService;
import com.uduemc.biso.node.web.api.service.WebSiteService;
import com.uduemc.biso.node.web.api.service.hostsetup.HSSystemDataNumService;

import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;

@RestController
@RequestMapping("/api/system/faq")
@Api(tags = "FAQ系统管理模块")
public class FaqController {

	private final Logger logger = LoggerFactory.getLogger(getClass());

	@Autowired
	private FaqService faqServiceImpl;

	@Autowired
	private SystemService systemServiceImpl;

	@Autowired
	private WebSiteService webSiteServiceImpl;

	@Autowired
	private HSSystemDataNumService hSSystemDataNumServiceImpl;

	@ApiOperation(value = "保存Faq系统", notes = "增加、修改Faq系统")
	@PostMapping("/save")
	public JsonResult save(@Valid @RequestBody RequestFaq requestFaq, BindingResult errors)
			throws JsonParseException, JsonMappingException, JsonProcessingException, IOException {
		if (errors.hasErrors()) {
			for (FieldError fieldError : errors.getFieldErrors()) {
				String defaultMessage = fieldError.getDefaultMessage();
				String field = fieldError.getField();
				logger.info("field: " + field + "defaultMessage: " + defaultMessage);
				return JsonResult.messageError(field + " " + defaultMessage);
			}
		}

		long systemId = requestFaq.getSystemId();
		SSystem sSystem = systemServiceImpl.getCurrentInfoById(systemId);
		if (sSystem == null || sSystem.getSystemTypeId() == null) {
			return JsonResult.illegal();
		}

		long id = requestFaq.getId();
		if (id < 1) {
			// 新增的情况下判断数据是否超过2000条
			int num = hSSystemDataNumServiceImpl.faqitemNum();
			int usedNum = hSSystemDataNumServiceImpl.usedFaqitemNum();
			if (usedNum >= num) {
				return JsonResult.messageError("已使用" + usedNum + "条FAQ数据，无法添加，请联系管理员！");
			}
		}

		logger.info(requestFaq.toString());
		Faq data = faqServiceImpl.save(requestFaq);
		webSiteServiceImpl.cacheClear(sSystem);
		return JsonResult.messageSuccess("保存成功", FilterResponse.filterRepertoryInfo(data));
	}

	@ApiOperation(value = "获取Faq数据", notes = "通过 faqId 获取单个Faq数据")
	@ApiImplicitParams({ @ApiImplicitParam(name = "faqId", value = "Faq ID", required = true) })
	@PostMapping("/info")
	public JsonResult info(@RequestParam("faqId") long faqId) throws JsonParseException, JsonMappingException, JsonProcessingException, IOException {
		if (faqId < 1) {
			return JsonResult.illegal();
		}

		Faq data = faqServiceImpl.fullInfoCurrent(faqId);
		if (data == null) {
			return JsonResult.assistance();
		}
		return JsonResult.ok(FilterResponse.filterRepertoryInfo(data));
	}

	@ApiOperation(value = "获取Faq列表数据", notes = "仅仅作用于次控段后台获取数据")
	@PostMapping("/table-data-list")
	public JsonResult tableDataList(@Valid @RequestBody RequestFaqTableDataList requestFaqTableDataList, BindingResult errors)
			throws JsonParseException, JsonMappingException, JsonProcessingException, IOException {
		if (errors.hasErrors()) {
			for (FieldError fieldError : errors.getFieldErrors()) {
				String defaultMessage = fieldError.getDefaultMessage();
				String field = fieldError.getField();
				logger.info("field: " + field + "defaultMessage: " + defaultMessage);
				return JsonResult.messageError(defaultMessage);
			}
		}
		requestFaqTableDataList.setIsRefuse((short) 0);
		PageInfo<FaqTableData> data = faqServiceImpl.infosByRequestFaqTableDataList(requestFaqTableDataList);
		return JsonResult.ok(data);
	}

	@ApiOperation(value = "修改是否显示状态", notes = "通过传入的参数 id 来指定对应的 Faq 数据，通过传入的参数 isShow 来修改指定 Faq 数据的是否显示状态")
	@ApiImplicitParams({ @ApiImplicitParam(name = "id", value = "Faq ID", required = true),
			@ApiImplicitParam(name = "isShow", value = "Faq 的 isShow 数据字段，1-显示 0-不显示", required = true) })
	@PostMapping("/change-show")
	public JsonResult changeShow(@RequestParam long id, @RequestParam short isShow)
			throws JsonParseException, JsonMappingException, JsonProcessingException, IOException, InterruptedException {
		if (id < 1L || isShow > (short) 1) {
			return JsonResult.illegal();
		}
		SFaq sFaq = faqServiceImpl.infoCurrent(id);
		if (sFaq == null) {
			return JsonResult.illegal();
		}
		sFaq.setIsShow(isShow);
		boolean bool = faqServiceImpl.updateBySFaq(sFaq);
		if (!bool) {
			return JsonResult.assistance();
		}
		webSiteServiceImpl.cacheClearSystemId(sFaq.getSystemId());
		return JsonResult.messageSuccess("操作成功", id);
	}

	@ApiOperation(value = "修改是否置顶状态", notes = "通过传入的参数 id 来指定对应的 Faq 数据，通过传入的参数 isTop 来修改指定 Faq 数据的是否置顶状态")
	@ApiImplicitParams({ @ApiImplicitParam(name = "id", value = "Faq ID", required = true),
			@ApiImplicitParam(name = "isTop", value = "Faq 的 isTop 数据字段，暂时只开放0、1这两种情况，0-不置顶，1-置顶，且置顶数据为1", required = true) })
	@PostMapping("/change-istop")
	public JsonResult changeIsTop(@RequestParam long id, @RequestParam short isTop)
			throws JsonParseException, JsonMappingException, JsonProcessingException, IOException, InterruptedException {
		if (id < 1L || isTop > (short) 1) {
			return JsonResult.illegal();
		}
		SFaq sFaq = faqServiceImpl.infoCurrent(id);
		if (sFaq == null) {
			return JsonResult.illegal();
		}
		sFaq.setIsTop(isTop);
		boolean bool = faqServiceImpl.updateBySFaq(sFaq);
		if (!bool) {
			return JsonResult.assistance();
		}
		webSiteServiceImpl.cacheClearSystemId(sFaq.getSystemId());
		return JsonResult.messageSuccess("操作成功", id);
	}

	@ApiOperation(value = "批量删除", notes = "通过传入的参数 ids 来指定要删除的 Faq 数据，适用于一条数据删除")
	@ApiImplicitParams({ @ApiImplicitParam(name = "ids", value = "要删除的 Faq ID，通过数组的方式提交，例如：[1,33,49] - 删除 Faq Id 1、33、49 这三条数据", required = true) })
	@PostMapping("/deletes")
	public JsonResult deletes(@RequestBody List<Long> ids)
			throws JsonParseException, JsonMappingException, JsonProcessingException, IOException, InterruptedException {
		if (CollectionUtils.isEmpty(ids)) {
			return JsonResult.illegal();
		}
		List<SFaq> listSFaq = new ArrayList<SFaq>();
		long systemId = 0;
		for (Long id : ids) {
			if (id == null || id.longValue() < 1) {
				return JsonResult.illegal();
			}

			SFaq sFaq = faqServiceImpl.infoCurrent(id);
			if (sFaq == null) {
				return JsonResult.illegal();
			}
			if (systemId == 0) {
				systemId = sFaq.getSystemId();
			}
			listSFaq.add(sFaq);
		}
		boolean bool = faqServiceImpl.deletes(listSFaq);
		if (!bool) {
			return JsonResult.assistance();
		}
		webSiteServiceImpl.cacheClearSystemId(systemId);
		return JsonResult.messageSuccess("批量删除成功", listSFaq);
	}

	@ApiOperation(value = "单个删除", notes = "通过传入的参数 id 来指定要删除的 Faq 数据")
	@ApiImplicitParams({ @ApiImplicitParam(name = "id", value = "要删除的 Faq ID", required = true) })
	@PostMapping("/delete")
	public JsonResult delete(@RequestParam long id)
			throws JsonParseException, JsonMappingException, JsonProcessingException, IOException, InterruptedException {
		if (id < 1) {
			return JsonResult.illegal();
		}
		List<SFaq> listSFaq = new ArrayList<SFaq>();
		SFaq sFaq = faqServiceImpl.infoCurrent(id);
		if (sFaq == null) {
			return JsonResult.illegal();
		}
		listSFaq.add(sFaq);
		boolean bool = faqServiceImpl.deletes(listSFaq);
		if (!bool) {
			return JsonResult.assistance();
		}
		long systemId = sFaq.getSystemId();
		webSiteServiceImpl.cacheClearSystemId(systemId);
		return JsonResult.messageSuccess("删除成功", sFaq);
	}

	@ApiOperation(value = "获取总数", notes = "通过传入的参数 systemId 获取 Faq 系统的数据总量，回收站，非回收站内的数据均可获取")
	@ApiImplicitParams({ @ApiImplicitParam(name = "systemId", value = "Faq系统的系统ID", required = true),
			@ApiImplicitParam(name = "categoryId", value = "Faq系统某一个分类的ID，传入0获取系统中所有的Faq数据总量，如果不为0则需要与对应的系统分类能够匹配上", required = true),
			@ApiImplicitParam(name = "isRefuse", value = "是否为回收站内的数据，默认0-非回收站，1回收站", required = false, defaultValue = "0") })
	@PostMapping("/total-by-system-category-id")
	public JsonResult totalBySystemCategoryId(@RequestParam("systemId") long systemId, @RequestParam("categoryId") long categoryId,
			@RequestParam(value = "isRefuse", required = false, defaultValue = "0") short isRefuse)
			throws JsonParseException, JsonMappingException, JsonProcessingException, IOException, InterruptedException {
		int total = faqServiceImpl.totalCurrentBySystemCategoryRefuseId(systemId, categoryId, isRefuse);
		return JsonResult.ok(total);
	}

	@PostMapping("/recycle-table-data-list")
	@ApiOperation(value = "Faq系统回收站", notes = "Faq系统回收站内的数据列表")
	public JsonResult recycleTableDataList(@Valid @RequestBody RequestFaqTableDataList requestFaqTableDataList, BindingResult errors)
			throws JsonParseException, JsonMappingException, JsonProcessingException, IOException {
		if (errors.hasErrors()) {
			for (FieldError fieldError : errors.getFieldErrors()) {
				String defaultMessage = fieldError.getDefaultMessage();
				String field = fieldError.getField();
				logger.info("field: " + field + "defaultMessage: " + defaultMessage);
				return JsonResult.messageError(defaultMessage);
			}
		}
		requestFaqTableDataList.setIsRefuse((short) 1);
		PageInfo<FaqTableData> data = faqServiceImpl.infosByRequestFaqTableDataList(requestFaqTableDataList);
		return JsonResult.ok(data);
	}

	@PostMapping("/reduction-recycle-any")
	@ApiOperation(value = "批量还原", notes = "回收站批量还原已经删除的数据")
	public JsonResult reductionRecycleAny(@RequestBody List<Long> ids)
			throws JsonParseException, JsonMappingException, JsonProcessingException, IOException, InterruptedException {
		if (CollectionUtils.isEmpty(ids)) {
			return JsonResult.illegal();
		}
		List<SFaq> listSFaq = new ArrayList<>();
		for (Long id : ids) {
			if (id == null || id.longValue() < 1) {
				return JsonResult.illegal();
			}

			SFaq sFaq = faqServiceImpl.infoCurrent(id);
			if (sFaq == null) {
				return JsonResult.illegal();
			}
			listSFaq.add(sFaq);
		}
		boolean bool = faqServiceImpl.reductionRecycle(listSFaq);
		if (!bool) {
			return JsonResult.assistance();
		}
		return JsonResult.messageSuccess("批量还原成功", listSFaq);
	}

	@PostMapping("/reduction-recycle-one")
	@ApiOperation(value = "还原单个", notes = "回收站还原单个已经删除的数据")
	public JsonResult reductionRecycleOne(@RequestParam long id)
			throws JsonParseException, JsonMappingException, JsonProcessingException, IOException, InterruptedException {
		if (id < 1) {
			return JsonResult.illegal();
		}
		List<SFaq> listSFaq = new ArrayList<>();
		SFaq sFaq = faqServiceImpl.infoCurrent(id);
		if (sFaq == null) {
			return JsonResult.illegal();
		}
		listSFaq.add(sFaq);
		boolean bool = faqServiceImpl.reductionRecycle(listSFaq);
		if (!bool) {
			return JsonResult.assistance();
		}
		return JsonResult.messageSuccess("还原成功", sFaq);
	}

	@PostMapping("/clean-recycle-all")
	@ApiOperation(value = "物理全部清除", notes = "物理清除回收站内所有数据，参入的参数为系统ID，成功后返回的数据也是系统ID")
	public JsonResult cleanRecycleAll(@RequestParam("systemId") long systemId)
			throws JsonParseException, JsonMappingException, JsonProcessingException, IOException, InterruptedException {
		if (systemId < 1) {
			return JsonResult.illegal();
		}

		SSystem system = systemServiceImpl.getCurrentInfoById(systemId);
		if (system == null) {
			return JsonResult.illegal();
		}

		boolean bool = faqServiceImpl.cleanRecycleAll(system);
		if (!bool) {
			return JsonResult.assistance();
		}
		return JsonResult.messageSuccess("清空" + system.getName() + "系统回收站成功", systemId);
	}

	@PostMapping("/clean-recycle-any")
	@ApiOperation(value = "物理批量清除", notes = "物理批量清除后无法恢复")
	public JsonResult cleanRecycleAny(@RequestBody List<Long> ids)
			throws JsonParseException, JsonMappingException, JsonProcessingException, IOException, InterruptedException {
		if (CollectionUtils.isEmpty(ids)) {
			return JsonResult.illegal();
		}
		List<SFaq> listSFaq = new ArrayList<>();
		for (Long id : ids) {
			if (id == null || id.longValue() < 1) {
				return JsonResult.illegal();
			}

			SFaq sFaq = faqServiceImpl.infoCurrent(id);
			if (sFaq == null) {
				return JsonResult.illegal();
			}
			listSFaq.add(sFaq);
		}

		boolean bool = faqServiceImpl.cleanRecycle(listSFaq);
		if (!bool) {
			return JsonResult.assistance();
		}
		return JsonResult.messageSuccess("批量清除成功", listSFaq);
	}

	@PostMapping("/clean-recycle-one")
	@ApiOperation(value = "物理单个清除", notes = "物理单个清除后无法恢复")
	public JsonResult cleanRecycleOne(@RequestParam long id)
			throws JsonParseException, JsonMappingException, JsonProcessingException, IOException, InterruptedException {
		if (id < 1) {
			return JsonResult.illegal();
		}
		List<SFaq> listSFaq = new ArrayList<>();
		SFaq sFaq = faqServiceImpl.infoCurrent(id);
		if (sFaq == null) {
			return JsonResult.illegal();
		}
		listSFaq.add(sFaq);
		boolean bool = faqServiceImpl.cleanRecycle(listSFaq);
		if (!bool) {
			return JsonResult.assistance();
		}
		return JsonResult.messageSuccess("清除成功", sFaq);
	}

}
